-module(p3).
%-export([main/0]).
-compile(export_all).

simple_prime_list(Bound) ->
    {Pr, _, _} = primes_list(Bound),
    Pr.

primes_list(Bound) when Bound =< 4 -> [3, 2];
primes_list(Bound) -> primes_list(Bound, [3, 2], {[2], 1}, 5). 

primes_list(Bound, {Primes, Z, X}) -> primes_list(Bound, Primes, Z, X).

primes_list(Bound, Primes, Z, X) 
    when X > Bound -> {Primes, Z, X};
primes_list(Bound, Primes, {_PrimesToCompare, Index}=Z, X) ->
    {NewCompare, Decr} = update_compare(Primes, Z, X),
    {NewPrimes, Incr} = update_primes(Primes, NewCompare, X),
    primes_list(Bound, NewPrimes, {NewCompare, Index + Incr - Decr}, X + 2).

update_primes(Primes, PrimesToCompare, X) ->
    case is_prime(X, PrimesToCompare) of
        true -> {[X | Primes], 1};
        false -> {Primes, 0}
    end.

update_compare(Primes, {PrimesToCompare, Index}, X) ->
    Sqrt = erlang:trunc(math:sqrt(X)),
    Elem = lists:nth(Index, Primes), 
    case Elem =< Sqrt of
        true -> {[Elem | PrimesToCompare], 1};
        false -> {PrimesToCompare, 0}
    end.

is_prime(X, [F]) -> X rem F =/= 0;
is_prime(X, [F | List]) -> 
    is_prime(X, [F]) and is_prime(X, List).
    
